#ifdef _MSC_VER
#include <crtdbg.h>
#endif
#include "sock.h"

in_addr_t inet_addr_ex(const char* host)
{
	struct in_addr result;
	result.s_addr = inet_addr(host);
	if (result.s_addr == INADDR_NONE) {
		struct hostent* ht = 0;
		if ((ht = gethostbyname(host)) != 0) {
			result = *((struct in_addr*)ht->h_addr);
		}
	}
#ifdef _MSC_VER
	return result.s_addr;
#elif __GNUC__
	return result.s_addr;
#endif
}

int sock_setnblock(SOCKET fd, int act) {
#ifdef WIN32
	unsigned int arg = (act ? 1 : 0);
	return ioctlsocket(fd, FIONBIO, &arg);
#else
	int flags = fcntl(fd, F_GETFL, 0);
	if (flags < 0)	{
		return -1;
	}
	if (act){
		if (flags & O_NONBLOCK)
			;
		else {
			return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
		}
	}
	else {
		if (flags & O_NONBLOCK) {
			flags &= ~O_NONBLOCK;
			return fcntl(fd, F_SETFL, flags);
		}			
	}
	return 0;

#endif
}

int sock_setndelay(SOCKET fd, int act) {
#ifndef TCP_NODELAY
	#define TCP_NODELAY 0x0001
#endif
	int bNoDelay = act;
	return (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY,
					 (char *) &bNoDelay, sizeof(bNoDelay)));
}

int sock_setlinger(SOCKET fd, u_short l_onoff, u_short l_linger)
{
	struct linger lin = {l_onoff, l_linger};
	return setsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&lin, sizeof(lin));
}

int sock_setkeepalive(SOCKET fd, int act) 
{
	unsigned int arg = (act ? 1 : 0);
	return (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
					 (char *) &arg, sizeof(arg)));
}

int sock_create_nb(int domain, int type, int protocol)
{
	int fd = socket(domain, type, protocol);
	if (fd != -1) {
		sock_setnblock(fd, 1);
	}
	return fd;
}
